﻿using AlgoritmoConstrutivo.entidades;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;

namespace AlgoritmoConstrutivo.leitor
{
    class XMLInstanceReader
    {

        private Grafo software ;
    

        GerenciadorNos gerenciaNo = new GerenciadorNos();

        public XMLInstanceReader()
        {

        }

    

        public Grafo ExtractInstance(FileInfo arquivo)
        {
            GerenciadorNos.reiniciaIds();
            this.software = new Grafo();
            XmlTextReader xtr = new XmlTextReader(arquivo.OpenRead());
            xtr.WhitespaceHandling = WhitespaceHandling.None;
            xtr.Read(); //le a declaração do XML, avança para o primeiro nó.

            while (xtr.Read())
            {
                if (xtr.Name == "context")
                {
                    if (xtr.GetAttribute("name")!=null)
                        software.Nome = xtr.GetAttribute("name").ToLower(); //nome do software a ser lido
                }
                else if (xtr.Name == "type" && xtr.IsStartElement())
                {
                    No modulo = null;
                    try
                    {
                        modulo =  this.gerenciaNo.InsertNo(xtr.GetAttribute("name"));
                        software.AddNo(modulo);
                    }

                    catch (NullReferenceException ex)
                    {
                        throw ex;
                    }


                    while (xtr.Name != "dependencies" && !xtr.EOF)
                        xtr.Read();

                    int numDependencias = Int32.Parse(xtr.GetAttribute("count"));

                    if (numDependencias == 0)
                        continue;

                    else
                    {
                        while (xtr.Name != "depends-on" && !xtr.EOF)
                            xtr.Read();

                        for (int i = 0; i < numDependencias; i++)
                        {
                            No vizinho = null;
                            try
                            {
                                String nomeModulo = xtr.GetAttribute("name");
                                if (nomeModulo == null)
                                    continue;

                                vizinho = this.gerenciaNo.InsertNo(nomeModulo);
                                software.AddNo(vizinho);

                                software.AdicionaArestaDirecionada(modulo.Id, vizinho.Id);

                            }
                            catch (Exception ex)
                            {

                                throw ex;
                            }

                           
                           
                            xtr.Read();
                        }
                        
                    }
                }
                   
            }

            xtr.Close();
            return this.software;
        }
    }
}
